<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue2.0-双向数据绑定的实现原理</title>
</head>
<body>
    姓名: <span id="spanName"></span>
    <br>
    <input type="text" id="iptName">


    <script>
        // ***vue 2.0 版本 ***
        /*  vue双向绑定原理采用数据劫持结合发布者-订阅者模式的方式，
            通过Object.defineProperty()来劫持各个属性的setter，getter，
            在数据变动时发布消息给订阅者，触发相应的监听回调。
        */
        let obj = {
            name:'',
        }
        // 克隆 -- 深拷贝
        let newObj = JSON.parse(JSON.stringify(obj));
        // Object.defineProperty() 方法会直接在一个对象上定义一个新属性，或者修改一个对象的现有属性，并返回此对象
        Object.defineProperty(obj,'name',{
            get(){
                return newObj.name;
            },
            set(val){
                if(val === newObj.name) return;
                newObj.name = val;
                observer();
            }
        });
        function observer(){
            spanName.innerHTML = obj.name;
            iptName.value = obj.name;
        }
        observer();
        setTimeout(() => {
            obj.name="学习" 
        }, 1000);

        // input的监听
        iptName.oninput = function(){
            obj.name = this.value; 
        }

        /*
            1.对原始数据克隆
            2.需要分别给对象中的每一个属性设置监听
        */
        
    </script>

</body>
</html>